﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Darkmoon.DX11Imported;

namespace WindowsFormsControlLibrary1
{
    public partial class UserControl1: UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
        }

        private void UserControl1_Load(object sender, EventArgs e)
        {
            LP_DXGI_SWAP_CHAIN_DESC pSCDesc = new LP_DXGI_SWAP_CHAIN_DESC();
            pSCDesc.Value.BufferCount = 2;
            pSCDesc.Value.BufferDesc.Width = (uint)ClientSize.Width;
            pSCDesc.Value.BufferDesc.Height = (uint)ClientSize.Height;
            pSCDesc.Value.BufferDesc.Format = DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM;
            pSCDesc.Value.BufferDesc.RefreshRate.Numerator = 60;
            pSCDesc.Value.BufferDesc.RefreshRate.Denominator = 1;
            pSCDesc.Value.BufferUsage = DXGI_USAGE.DXGI_USAGE_RENDER_TARGET_OUTPUT;
            pSCDesc.Value.OutputWindow = Handle;
            pSCDesc.Value.SampleDesc.Count = 1;
            pSCDesc.Value.SampleDesc.Quality = 0;
            pSCDesc.Value.Windowed = 1;

            System.Threading.ManualResetEventSlim wait = new System.Threading.ManualResetEventSlim(false);
            System.Threading.Thread thd_Render = new System.Threading.Thread(() =>
            {
                disp = System.Windows.Threading.Dispatcher.CurrentDispatcher;
                wait.Set();
                System.Windows.Threading.Dispatcher.Run();
            });
            thd_Render.Start();
            wait.Wait();
            if (disp != null)
            {
                disp.BeginInvoke(new Action(() =>
                {
                    DX11ImportLib_GlobalMethods.D3D11CreateDeviceAndSwapChain(ref pSCDesc.Value,
                        ppSwapChain: out pSwapChain, ppImmediateContext: out pDC, ppDevice: out pDevice);

                    object pBackBufferRaw = null;
                    pSwapChain.GetBuffer(0, DX11_Guids_And_Consts.IID_ID3D11Texture2D, out pBackBufferRaw);
                    pBackBuffer = (ID3D11Texture2D)pBackBufferRaw;
                    pDevice.CreateRenderTargetView(pBackBuffer, out pRTV);
                    pDC.OMSetRenderTargets(pRTV);

                    D3D11_VIEWPORT vp;
                    vp.Width = ClientSize.Width;
                    vp.Height = ClientSize.Height;
                    vp.MinDepth = 0.0f;
                    vp.MaxDepth = 1.0f;
                    vp.TopLeftX = 0;
                    vp.TopLeftY = 0;
                    pDC.RSSetViewports(vp);

                    D3D11_FEATURE_DATA_DOUBLES fo = new D3D11_FEATURE_DATA_DOUBLES();
                    pDevice.CheckFeatureSupport(out fo);

                }));
            }
            timer = new System.Threading.Timer(state =>
            {
                float[] color = new float[] { (float)ran.NextDouble(), (float)ran.NextDouble(), (float)ran.NextDouble(), 1.0f };
                pDC.ClearRenderTargetView(pRTV, color);
                var rv = pSwapChain.Present(0, new DXGI_PRESENT());
                if (rv == DXGI_STATUS.DXGI_STATUS_OCCLUDED)
                {
                    int a = 0;
                }
            }, null, 1000, 1000);
        }

        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0002 /*WM_DESTROY*/)
            {
                if (disp != null) disp.BeginInvokeShutdown(System.Windows.Threading.DispatcherPriority.Normal);
            }
            base.WndProc(ref m);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            if (disp != null)
            {
                disp.BeginInvoke(new Action(() =>
                {
                    pSwapChain.Present(0, DXGI_PRESENT.DXGI_PRESENT_DO_NOT_SEQUENCE);
                }));
            }
            //base.OnPaint(e);
        }

        System.Windows.Threading.Dispatcher disp = null;
        System.Threading.Timer timer = null;
        Random ran = new Random();
        ID3D11Texture2D pBackBuffer = null;
        ID3D11Device pDevice = null;
        ID3D11DeviceContext pDC = null;
        IDXGISwapChain pSwapChain = null;
        ID3D11RenderTargetView pRTV = null;
    }
}
